package com.bjpowernode.crm.workbench.service.impl;

import com.bjpowernode.crm.commons.contants.Contants;
import com.bjpowernode.crm.commons.utils.DateUtils;
import com.bjpowernode.crm.commons.utils.UUIDUtils;
import com.bjpowernode.crm.settings.domain.User;
import com.bjpowernode.crm.settings.service.DicValueService;
import com.bjpowernode.crm.settings.service.UserService;
import com.bjpowernode.crm.workbench.domain.*;
import com.bjpowernode.crm.workbench.dto.ClueQueryDto;
import com.bjpowernode.crm.workbench.dto.ClueConvertingDto;
import com.bjpowernode.crm.workbench.mapper.ClueMapper;
import com.bjpowernode.crm.workbench.service.*;
import lombok.Getter;
import lombok.Setter;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Getter
@Setter
public class ClueServiceImpl implements ClueService {

    /**
     * 访问线索数据
     */
    private ClueMapper clueMapper;

    /**
     * 处理用户相关业务
     */
    private UserService userService;

    /**
     * 处理字典值相关业务
     */
    private DicValueService dicValueService;

    /**
     * 处理市场活动相关业务
     */
    private ActivityService activityService;

    /**
     * 处理客户相关业务
     */
    private CustomerService customerService;

    /**
     * 处理联系人相关业务
     */
    private ContactsService contactsService;

    /**
     * 处理线索备注相关业务
     */
    private ClueRemarkService clueRemarkService;

    /**
     * 处理客户备注相关业务
     */
    private CustomerRemarkService customerRemarkService;

    /**
     * 处理联系人备注相关业务
     */
    private ContactsRemarkService contactsRemarkService;

    /**
     * 处理线索与市场活动关联相关的业务
     */
    private ClueActivityRelationService clueActivityRelationService;

    /**
     * 处理联系人与市场活动关联关系的相关业务
     */
    private ContactsActivityRelationService contactsActivityRelationService;

    /**
     * 处理交易相关业务
     */
    private TranService tranService;

    /**
     * 处理交易备注相关业务
     */
    private TranRemarkService tranRemarkService;

    @Override
    public void insertClue(Clue clue, HttpSession session) {
        User user = (User) session.getAttribute(Contants.SESSION_USER);
        String formattedDateTime = DateUtils.formatDateTime(new Date());

        clue.setId(UUIDUtils.getUUID());
        clue.setCreateBy(user.getId());
        clue.setCreateTime(formattedDateTime);
        clue.setEditBy(user.getId());
        clue.setEditTime(formattedDateTime);

        this.clueMapper.insertClue(clue);
    }

    @Override
    public Clue queryClueById(String id) {
        Clue clue = this.clueMapper.selectClueById(id);

        if (clue == null) {
            return null;
        }

        //线索中存储的是所有者、创建者、最后一个编辑者的 id，结果中需要的是他们的名称
        clue.setOwner(this.userService.queryNameById(clue.getOwner()));
        clue.setCreateBy(this.userService.queryNameById(clue.getCreateBy()));
        clue.setEditBy(this.userService.queryNameById(clue.getEditBy()));

        //数据库中存储的是称呼、状态、来源的字典 id ，结果中需要的是它们的字典值
        clue.setAppellation(this.dicValueService.queryValueById(clue.getAppellation()));
        clue.setState(this.dicValueService.queryValueById(clue.getState()));
        clue.setSource(dicValueService.queryValueById(clue.getSource()));

        return clue;
    }

    @Override
    public List<Clue> queryCluesByConditions(ClueQueryDto clueQueryDto) {
        List<Clue> clues = this.clueMapper.selectCluesByConditions(clueQueryDto);

        for (Clue clue : clues) {
            //线索中存放的是来源市场活动的 id ，页面需要显示的是来源市场活动的名称
//            clue.setSource(this.activityService.queryNameById(clue.getSource()));

            //搞错了，是显示文本
//            clue.setSource(this.dicValueService.queryTextById(clue.getSource()));
            //text应该是描述，这里应该需要的是字典值，值应该是 value
            clue.setSource(this.dicValueService.queryValueById(clue.getSource()));

            //线索中存放的是所有者的 id ，页面需要的是所有者的名称
            clue.setOwner(this.userService.queryNameById(clue.getOwner()));

            //数据库中存放的是对应状态在字典值中的 id ，页面需要的是该字典值的显示文本
//            clue.setState(this.dicValueService.queryTextById(clue.getState()));
            clue.setState(this.dicValueService.queryValueById(clue.getState()));
        }

        return clues;
    }

    @Override
    public void convertClue(ClueConvertingDto clueConvertingDto, User currentUser) {
        //首先查询预转换的线索
        Clue clue = this.clueMapper.selectClueById(clueConvertingDto.getClueId());

//将线索中公司部分的信息转换成客户信息
        String idOfCustomer = this.convertClueToCustomer(clue, currentUser.getId());

        //将线索中的个人信息转换成联系人信息
        String idOfContact = this.convertClueToContacts(clue, currentUser.getId(), idOfCustomer);

        //将线索的备注转换成客户备注和联系人备注
        List<ClueRemark> clueRemarks = this.clueRemarkService.queryClueRemarkByClueId(clue.getId());

        if (clueRemarks != null && !clueRemarks.isEmpty()) {//线索备注不为空
            this.convertClueRemarksToCustomerRemarks(clueRemarks, idOfCustomer);
            this.convertClueRemarksToContactsRemarks(clueRemarks, idOfContact);
        }

        //将该线索与市场活动的关联关系转换成联系人与市场活动的关联关系
//        List<ClueActivityRelation> clueActivityRelations = this.clueActivityRelationService.queryClueActivityRelationsByClueId(convertingClueDto.getClueId());

        List<String> idsOfRelatedActivities = this.clueActivityRelationService.queryIdsOfRelatedActivities(clueConvertingDto.getClueId());

        if (idsOfRelatedActivities != null && !idsOfRelatedActivities.isEmpty()) {//该线索有关联市场活动
            this.convertClueActivityRelationToContactsActivityRelation(idOfContact, idsOfRelatedActivities);
        }

        //如果需要创建交易，变创建交易，并将线索备注转换至交易备注
        if (clueConvertingDto.getIsCreateTran() != null && clueConvertingDto.getIsCreateTran()) {//需要创建交易
            String idOfTran = this.createTran(clueConvertingDto.getActivityId(), idOfContact, currentUser.getId(), idOfCustomer, clueConvertingDto.getExpectedDate(), clueConvertingDto.getMoney(), clueConvertingDto.getName(), clueConvertingDto.getStage());

            if (clueRemarks != null && !clueRemarks.isEmpty()) {//该线索下有备注，需要将它们转换成交易备注
                this.convertClueRemarkToTranRemark(clueRemarks, idOfTran);
            }

        }

        //删除该线索的所有备注
        this.clueRemarkService.removeClueRemarkByClueId(clueConvertingDto.getClueId());

        //删除该线索与市场活动的所有关联关系
        this.clueActivityRelationService.removeClueActivityRelationsByClueId(clueConvertingDto.getClueId());

        //删除线索
        this.clueMapper.deleteClueById(clue.getId());
    }

    /**
     * 将线索中的公司信息转换成客户信息
     *
     * @param clue     预转换的线索
     * @param idOfUser 当前用户的 id
     * @return 客户 id
     */
    private String convertClueToCustomer(Clue clue, String idOfUser) {
        String formattedDate = DateUtils.formatDateTime(new Date());

        //模型转换
        Customer customer = new Customer();
        customer.setAddress(clue.getAddress());
        customer.setContactSummary(clue.getContactSummary());
        customer.setCreateBy(idOfUser);
        customer.setCreateTime(formattedDate);
        customer.setDescription(clue.getDescription());
        customer.setId(UUIDUtils.getUUID());
        customer.setName(clue.getCompany());
        customer.setNextContactTime(clue.getNextContactTime());
        customer.setOwner(idOfUser);
        customer.setPhone(clue.getPhone());
        customer.setWebsite(clue.getWebsite());
        customer.setEditBy(idOfUser);
        customer.setEditTime(formattedDate);

        this.customerService.addCustomer(customer);
        return customer.getId();
    }

    /**
     * 将线索中的个人信息转换成联系人
     *
     * @param clue         线索
     * @param idOfUser     当前用户的 id
     * @param idOfCustomer 所属客户的 id
     * @return 联系人的 id
     */
    private String convertClueToContacts(Clue clue, String idOfUser, String idOfCustomer) {
        Contacts contacts = new Contacts();
        String formattedDate = DateUtils.formatDateTime(new Date());

        //模型转换，新增
        contacts.setAddress(clue.getAddress());
        contacts.setAppellation(clue.getAppellation());
        contacts.setContactSummary(clue.getContactSummary());
        contacts.setCreateBy(idOfUser);
        contacts.setCreateTime(formattedDate);
        contacts.setEditBy(idOfUser);
        contacts.setEditTime(formattedDate);
        contacts.setCustomerId(idOfCustomer);
        contacts.setDescription(clue.getDescription());
        contacts.setEmail(clue.getEmail());
        contacts.setFullname(clue.getFullname());
        contacts.setId(UUIDUtils.getUUID());
        contacts.setJob(clue.getJob());
        contacts.setMphone(clue.getMphone());
        contacts.setNextContactTime(clue.getNextContactTime());
        contacts.setOwner(idOfUser);
        contacts.setSource(clue.getSource());

        this.contactsService.addContacts(contacts);
        return contacts.getId();
    }

    /**
     * 将线索备注转换成客户备注
     *
     * @param clueRemarks  线索备注列表
     * @param idOfCustomer 客户 id
     */
    private void convertClueRemarksToCustomerRemarks(List<ClueRemark> clueRemarks, String idOfCustomer) {
        //模型转换，批量新增
        List<CustomerRemark> customerRemarkList = new ArrayList<>(clueRemarks.size());
        CustomerRemark customerRemark = null;

        for (ClueRemark clueRemark : clueRemarks) {
            customerRemark = new CustomerRemark();

            customerRemark.setCreateBy(clueRemark.getCreateBy());
            customerRemark.setCreateTime(clueRemark.getCreateTime());
            customerRemark.setCustomerId(idOfCustomer);
            customerRemark.setEditBy(clueRemark.getEditBy());
            customerRemark.setEditFlag(clueRemark.getEditFlag());
            customerRemark.setEditTime(clueRemark.getEditTime());
            customerRemark.setId(UUIDUtils.getUUID());
            customerRemark.setNoteContent(clueRemark.getNoteContent());

            customerRemarkList.add(customerRemark);
        }

        this.customerRemarkService.addCustomerRemarks(customerRemarkList);
    }

    /**
     * 将线索备注转换成联系人备注
     *
     * @param clueRemarks  线索备注列表
     * @param idOfContacts 联系人 id
     */
    private void convertClueRemarksToContactsRemarks(List<ClueRemark> clueRemarks, String idOfContact) {
        //模型转换，批量新增
        List<ContactsRemark> contactsRemarkList = new ArrayList<>(clueRemarks.size());
        ContactsRemark contactsRemark = null;

        for (ClueRemark clueRemark : clueRemarks) {
            contactsRemark = new ContactsRemark();

            contactsRemark.setContactsId(idOfContact);
            contactsRemark.setCreateBy(clueRemark.getCreateBy());
            contactsRemark.setCreateTime(clueRemark.getCreateTime());
            contactsRemark.setEditBy(clueRemark.getEditBy());
            contactsRemark.setEditFlag(clueRemark.getEditFlag());
            contactsRemark.setEditTime(clueRemark.getEditTime());
            contactsRemark.setId(UUIDUtils.getUUID());
            contactsRemark.setNoteContent(clueRemark.getNoteContent());

            contactsRemarkList.add(contactsRemark);
        }

        this.contactsRemarkService.addContactsRemarks(contactsRemarkList);
    }

    /**
     * 将线索与市场活动的关联关系转换为联系人与市场活动的关联关系
     *
     * @param idOfContact     联系人的 id
     * @param idsOfActivities 市场活动的 id 列表
     */
    private void convertClueActivityRelationToContactsActivityRelation(String idOfContact, List<String> idsOfActivities) {
        //模型封装，新增
        List<ContactsActivityRelation> contactsActivityRelations = new ArrayList<>(idsOfActivities.size());
        ContactsActivityRelation temp = null;

        for (String idOfActivity : idsOfActivities) {
            temp = new ContactsActivityRelation();
            temp.setActivityId(idOfActivity);
            temp.setContactsId(idOfContact);
            temp.setId(UUIDUtils.getUUID());

            contactsActivityRelations.add(temp);
        }

        this.contactsActivityRelationService.addContactsActivityRelations(contactsActivityRelations);
    }

    /**
     * 创建交易
     *
     * @param idOfActivity 市场活动的 id
     * @param idOfContact  联系人的 id
     * @param idOfUser     用户的 id
     * @param idOfCustomer 客户的 id
     * @param expectedDate 期望日期
     * @param money        金额
     * @param name         名称
     * @param stage        阶段
     * @return 交易 id
     */
    private String createTran(String idOfActivity, String idOfContact, String idOfUser, String idOfCustomer, String expectedDate, String money, String name, String stage) {
        Tran tran = new Tran();
        String formattedDate = DateUtils.formatDateTime(new Date());

        tran.setActivityId(idOfActivity);
        tran.setContactsId(idOfContact);
        tran.setCreateBy(idOfUser);
        tran.setCreateTime(formattedDate);
        tran.setEditBy(idOfUser);
        tran.setEditTime(formattedDate);
        tran.setCustomerId(idOfCustomer);
        tran.setExpectedDate(expectedDate);
        tran.setId(UUIDUtils.getUUID());
        tran.setMoney(money);
        tran.setName(name);
        tran.setOwner(idOfUser);
        tran.setStage(stage);

        this.tranService.addTran(tran);
        return tran.getId();
    }

    /**
     * 将线索备注转换成交易备注
     *
     * @param clueRemarks 线索备注列表
     * @param idOfTran    交易 id
     */
    private void convertClueRemarkToTranRemark(List<ClueRemark> clueRemarks, String idOfTran) {
        List<TranRemark> tranRemarks = new ArrayList<>(clueRemarks.size());
        TranRemark temp = null;

        for (ClueRemark clueRemark : clueRemarks) {
            temp = new TranRemark();

            temp.setCreateBy(clueRemark.getCreateBy());
            temp.setCreateTime(clueRemark.getCreateTime());
            temp.setEditBy(clueRemark.getEditBy());
            temp.setEditFlag(clueRemark.getEditFlag());
            temp.setEditTime(clueRemark.getEditTime());
            temp.setId(UUIDUtils.getUUID());
            temp.setNoteContent(clueRemark.getNoteContent());
            temp.setTranId(idOfTran);

            tranRemarks.add(temp);
        }

        this.tranRemarkService.addTranRemarks(tranRemarks);
    }

    @Override
    public void deleteClueById(String id) {
        this.clueMapper.deleteClueById(id);
    }

}
